package chapterSystem.client.interfaceDrawing.activities;

import chapterSystem.client.ChapterSystemService;
import chapterSystem.client.callbacks.LoggCallback;
import chapterSystem.client.interfaceDrawing.InterfaceProvider;
import chapterSystem.client.model.entities.BrotherEntity;
import chapterSystem.client.model.entitiesInt.Brother;
import chapterSystem.client.model.entitiesInt.Unit;
import chapterSystem.client.model.enums.ActivityType;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * User: Hasp
 * Date: 08.04.12
 * Time: 1:05
 */
public class AddNewBrotherActivity extends Activity {
    final private Activity callbackActivity;

    public AddNewBrotherActivity(final Brother brother, final Activity callbackActivity) {
        super(brother, ActivityType.NEW_BROTHER);
        this.callbackActivity = callbackActivity;
    }

    @Override
    public void drawActivity(final StackLayoutPanel workArea) {
        ChapterSystemService.App.getInstance().getAllUnits(new AddBrotherInfCallback(workArea));
    }

    private class AddBrotherInfCallback implements AsyncCallback<Map<String, Unit>> {

        private StackLayoutPanel workArea;

        private AddBrotherInfCallback(StackLayoutPanel workArea) {
            this.workArea = workArea;
        }

        @Override
        public void onFailure(final Throwable caught) {
            Window.alert("Error: " + caught.getMessage());
        }

        @Override
        public void onSuccess(final Map<String, Unit> result) {
            workArea.clear();

            final FlexTable table = new FlexTable();
            final VerticalPanel form = new VerticalPanel();
            form.setSize("100%", "100%");
            form.add(table);

            final InterfaceProvider interfaceProvider = InterfaceProvider.getInstance();

            final TextArea nameField = interfaceProvider.createTextField();
            final ListBox unitId = fillUnitList(result.keySet());
            final TextArea rankBattleField = interfaceProvider.createTextField();
            final TextArea rankWork = interfaceProvider.createTextField();
            final TextArea pointsField = interfaceProvider.createTextField();

            final PasswordTextBox passwordField = new PasswordTextBox();
            final PasswordTextBox confirmPasswordField = new PasswordTextBox();
            final Label passwordLabel = new Label("Enter password: ");
            final Label confirmPasswordLabel = new Label("Confirm password: ");

            final List<Widget> passwordList = Arrays.<Widget>asList(passwordField, passwordLabel,
                    confirmPasswordField, confirmPasswordLabel);

            for (Widget w : passwordList) {
                w.setVisible(false);
                w.setHeight("25px");
            }

            final CheckBox needCreateAccount = new CheckBox("Create account");
            needCreateAccount.setValue(false);
            needCreateAccount.addValueChangeHandler(new ValueChangeHandler<Boolean>() {
                @Override
                public void onValueChange(ValueChangeEvent<Boolean> booleanValueChangeEvent) {
                    for (Widget w : passwordList) {
                        w.setVisible(booleanValueChangeEvent.getValue());
                    }
                }
            });

            table.setText(0, 0, "Name: ");
            table.setText(1, 0, "Unit: ");
            table.setText(2, 0, "Battle Rank: ");
            table.setText(3, 0, "Work Rank: ");
            table.setText(4, 0, "Points: ");
            table.setWidget(5, 0, needCreateAccount);

            table.setWidget(0, 1, nameField);
            table.setWidget(1, 1, unitId);
            table.setWidget(2, 1, rankBattleField);
            table.setWidget(3, 1, rankWork);
            table.setWidget(4, 1, pointsField);

            table.setWidget(6, 0, passwordLabel);
            table.setWidget(6, 1, passwordField);
            table.setWidget(7, 0, confirmPasswordLabel);
            table.setWidget(7, 1, confirmPasswordField);

            Button submitReportButton = new Button("Submit");
            submitReportButton.addClickHandler(new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                    boolean hasErrors = false;
                    System.out.println("Submit button was pushed");

                    if (nameField.getText().trim().length() == 0) {
                        hasErrors = true;
                        table.setText(0, 2, "Enter name");
                    }

                    try {
                        final int newRankBattle = Integer.parseInt(rankBattleField.getText().trim());
                        if (newRankBattle < 0) {
                            hasErrors = true;
                            table.setText(2, 2, "Must be nonnegative int");
                        } else if (!(newRankBattle < brother.getRankBattle() ||
                                newRankBattle == 0 && brother.getRankBattle() == 0)) {
                            hasErrors = true;
                            table.setText(2, 2, "Must be < your rank");
                        }
                    } catch (NumberFormatException e) {
                        hasErrors = true;
                        table.setText(2, 2, "Must be int");
                    }

                    try {
                        final int newRankWork = Integer.parseInt(rankWork.getText().trim());
                        if (newRankWork < 0) {
                            hasErrors = true;
                            table.setText(3, 2, "Must be nonnegative int");
                        } else if (!(newRankWork < brother.getRankWork() || newRankWork == 0 && brother.getRankWork() == 0)) {
                            hasErrors = true;
                            table.setText(3, 2, "Must be < your rank");
                        }
                    } catch (NumberFormatException e) {
                        hasErrors = true;
                        table.setText(3, 2, "Must be int");
                    }

                    try {
                        if (Integer.parseInt(pointsField.getText().trim()) < 0) {
                            hasErrors = true;
                            table.setText(4, 2, "Must be nonnegative int");
                        }
                    } catch (NumberFormatException e) {
                        hasErrors = true;
                        table.setText(4, 2, "Must be int");
                    }

                    if (passwordField.isVisible()) {
                        if (passwordField.getText().trim().length() == 0) {
                            hasErrors = true;
                            table.setText(6, 2, "Enter password");
                        } else if (!passwordField.getText().equals(confirmPasswordField.getText())) {
                            hasErrors = true;
                            table.setText(7, 2, "Passwords aren't equal");
                        }
                    }

                    if (hasErrors) return;

                    final Unit selectedUnit = result.get(unitId.getValue(unitId.getSelectedIndex()));
                    final Brother newBrother = new BrotherEntity(0, Integer.parseInt(rankBattleField.getText().trim()),
                            selectedUnit.getId(),
                            nameField.getText(),
                            Integer.parseInt(rankWork.getText().trim()), Integer.parseInt(pointsField.getText().trim()));
                    ChapterSystemService.App.getInstance().createNewBrother(newBrother,
                            passwordField.isVisible() ? passwordField.getText() : null, new AddNewBrotherCallback(workArea));
                    ChapterSystemService.App.getInstance().addLog(brother.getId(), id, "Add new brother: " + newBrother,
                            new LoggCallback());
                }
            });

            form.add(submitReportButton);

            workArea.add(form, new HTML("Add New Brother"), 4);
        }

        private ListBox fillUnitList(final Set<String> units) {
            ListBox lb = new ListBox();
            for (final String unit : units) {
                lb.addItem(unit);
            }
            return lb;
        }
    }

    private class AddNewBrotherCallback implements AsyncCallback<String> {
        private StackLayoutPanel workArea;

        private AddNewBrotherCallback(StackLayoutPanel workArea) {
            this.workArea = workArea;
        }


        @Override
        public void onFailure(Throwable caught) {
            Window.alert("Error: " + caught.getMessage());
        }

        @Override
        public void onSuccess(String result) {
            if ("Ok".equals(result)) {
                Window.alert("Created");
                AddNewBrotherActivity.this.callbackActivity.drawActivity(workArea);
            } else {
                Window.alert("Error: " + result);
            }
        }
    }
}
